#include <controller/TLSController.h>
#include <localview/LocalView.h>
#include <localview/Network.h>
#include <controller/TimeIncrementCalculationStrategy.h>
#include <controller/TimeIncrementFixedCycleStrategy.h>
#include <controller/CaseFuzzy.h>
#include <evolutive/TimeIncrementEvolutiveStrategy.h>
#include <controller/Case.h>
#include <log.h>
#include <iostream>

TLSController::TLSController(std::string strategy, std::string tlsId, localview::Network* network) {

	mLocalView = new localview::LocalView(tlsId, network);

	mStrategyId = strategy;

	mCaseFuzzy = CaseFuzzy::getInstance();

	mActivePhaseCalc = -1;

	rsi::log("TLSController", __FILE__, __LINE__, "Created a new controller %s", tlsId.c_str());
}

TLSController::~TLSController() {
}

void TLSController::startPhaseIncrementCalc(int phaseId, int timestep) {
	rsi::log("controller", __FILE__, __LINE__, "Starting Increment calc to tls: %s, phase: %d", mLocalView->getTLSId().c_str(), phaseId);

	TimeIncrementCalculationStrategy* strategy = createStrategy(mStrategyId);

	registerBackgroundCalcTask(strategy, phaseId);

	strategy->start(mLocalView, phaseId, timestep);
}

int TLSController::getPhaseIncrement(int phaseId) {

#ifdef DEBUG
    //Just to assure that we are returning the value to the right phase
    if(phaseId != mActivePhaseCalc) std::cout << "ERROR - Retrieving value to the wrong phase";
#endif

	mActiveCalc->stop();

	Case* c = mActiveCalc->getResult();

	int extension = mCaseFuzzy->desfuzzyfyExtension(c->getLocalGreenExtension());

	delete mActiveCalc;
	mActiveCalc = 0;

	return extension;
}

void TLSController::registerBackgroundCalcTask(TimeIncrementCalculationStrategy* tics, int phaseId) {
    mActivePhaseCalc = phaseId;
	mActiveCalc = tics;
}

TimeIncrementCalculationStrategy* TLSController::createStrategy(std::string strategy) {

    TimeIncrementCalculationStrategy* strategyObj = 0;

    if(strategy == "adaptative") {
        strategyObj = new TimeIncrementEvolutiveStrategy();
    } else if(strategy == "fixed_cycle") {
        strategyObj = new TimeIncrementFixedCycleStrategy();
    }

    return strategyObj;
}

